package com.vibration.web.controller.baseinfo;

import java.io.*;
import java.math.BigDecimal;
import java.net.Socket;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletResponse;

import com.mathworks.toolbox.javabuilder.MWException;
import com.vibration.baseinfo.domain.CzEquipment;
import com.vibration.baseinfo.domain.CzTemperatureData;
import com.vibration.baseinfo.domain.TaskCountModel;
import com.vibration.baseinfo.service.ICzEquipmentService;
import com.vibration.baseinfo.service.ICzTemperatureDataService;
import com.vibration.common.config.VibrationConfig;
import com.vibration.common.constant.Constants;
import com.vibration.framework.config.ServerConfig;
import com.vibration.socket.util.SocketUtil;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.vibration.common.annotation.Log;
import com.vibration.common.core.controller.BaseController;
import com.vibration.common.core.domain.AjaxResult;
import com.vibration.common.enums.BusinessType;
import com.vibration.baseinfo.domain.CzCollectionTask;
import com.vibration.baseinfo.service.ICzCollectionTaskService;
import com.vibration.common.utils.poi.ExcelUtil;
import com.vibration.common.core.page.TableDataInfo;

/**
 * 任务数据Controller
 * 
 * @author wu
 * @date 2022-08-11
 */
@RestController
@RequestMapping("/baseinfo/collectionTask")
public class CzCollectionTaskController extends BaseController
{
    @Autowired
    private ICzCollectionTaskService czCollectionTaskService;
    @Autowired
    private ServerConfig serverConfig;
    @Autowired
    private ICzTemperatureDataService czTemperatureDataService;
    @Autowired
    private ICzEquipmentService equipmentService;

    /**
     * 查询任务数据列表
     */
    @PreAuthorize("@ss.hasPermi('baseinfo:collectionTask:list')")
    @GetMapping("/list")
    public TableDataInfo list(CzCollectionTask czCollectionTask)
    {
        startPage();
        List<CzCollectionTask> list = czCollectionTaskService.selectCzCollectionTaskList(czCollectionTask);
        return getDataTable(list);
    }

    /**
     * 导出任务数据列表
     */
    @PreAuthorize("@ss.hasPermi('baseinfo:collectionTask:export')")
    @Log(title = "任务数据", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, CzCollectionTask czCollectionTask)
    {
        List<CzCollectionTask> list = czCollectionTaskService.selectCzCollectionTaskList(czCollectionTask);
        ExcelUtil<CzCollectionTask> util = new ExcelUtil<CzCollectionTask>(CzCollectionTask.class);
        util.exportExcel(response, list, "任务数据数据");
    }

    /**
     * 获取任务数据详细信息
     */
    @PreAuthorize("@ss.hasPermi('baseinfo:collectionTask:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo (@PathVariable("id") Long id) throws Exception
    {
        CzCollectionTask task = czCollectionTaskService.selectCzCollectionTaskById(id);
        if(task.getInversionStatus().equals("2")){
            String url = serverConfig.getUrl()+ Constants.RESOURCE_PREFIX + "/inversion/"+task.getId()+"/";
            task.setDataFile(url);
        }
        return AjaxResult.success(task);
    }

    /**
     * 任务统计
     */
    @GetMapping(value = "/taskCount")
    public AjaxResult taskCount ()
    {
        //震动任务
        List<TaskCountModel> zd = czCollectionTaskService.taskCountByType(0);
        //温度
        List<TaskCountModel> wd = czCollectionTaskService.taskCountByType(1);
        AjaxResult result = AjaxResult.success();
        result.put("zd",zd);
        result.put("wd",wd);
        return result;
    }

    /**
     * 新增任务数据
     */
    @PreAuthorize("@ss.hasPermi('baseinfo:collectionTask:add')")
    @Log(title = "任务数据", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody CzCollectionTask czCollectionTask)
    {
        czCollectionTask.setCreateUser(getUserId());
        AjaxResult result = AjaxResult.success();
        CzCollectionTask cct = czCollectionTaskService.insertCzCollectionTask(czCollectionTask);
        result.put("data",cct);
        return result;
    }

    /**
     * 停止任务
     */

    @Log(title = "停止任务", businessType = BusinessType.INSERT)
    @PostMapping("/stopTask")
    public AjaxResult stopTask(@RequestBody CzCollectionTask czCollectionTask)
    {

        czCollectionTaskService.stopCzCollectionTask(czCollectionTask);
        return AjaxResult.success();
    }

    /**
     * 反演
     */
    @Log(title = "反演", businessType = BusinessType.INSERT)
    @PostMapping("/inversion")
    public void inversion(@RequestBody CzCollectionTask czCollectionTask)throws MWException
    {
        Long taskId = czCollectionTaskService.inversionTask(czCollectionTask);
    }

    /**
     * 时域频域分析
     * @param czCollectionTask
     * @return
     * @throws Exception
     */
    @PostMapping("/analyse")
    public AjaxResult analyse(@RequestBody CzCollectionTask czCollectionTask) throws Exception
    {
        return AjaxResult.success(czCollectionTaskService.analyse(czCollectionTask));
    }

    /**
     * 线热源法
     * 计算导热系数
     */
    @PostMapping("/heatConduction")
    public AjaxResult heatConduction(@RequestBody CzCollectionTask collectionTask) throws Exception {
        return AjaxResult.success(czCollectionTaskService.heatConduction(collectionTask));
    }


    /**
     * 热比较法
     * 计算导热系数
     */
    @PostMapping("/heatConductionByCompare")
    public CzCollectionTask heatConductionByHeatCompare(@RequestBody CzCollectionTask collectionTask) throws MWException {
        return czCollectionTaskService.heatConductionByHeatCompare(collectionTask);
    }

    /**
     * 获取反演状态
     */
    @GetMapping("/getInversionStatus")
    public AjaxResult getInversionStatus()
    {
        AjaxResult result = AjaxResult.success();
        result.put("data", SocketUtil.inversionTask);
        return result;
    }
    @GetMapping("/checkTempById/{id}")
    public AjaxResult checkTempById(@PathVariable("id")String id)
    {
        CzTemperatureData ctd = czTemperatureDataService.checkTempById(id);
        AjaxResult result = AjaxResult.success();
        result.put("data", ctd);
        return result;
    }
    @GetMapping("/stopGetTemp/{id}")
    public AjaxResult stopGetTemp(@PathVariable("id")Long id) {
        //停止加热
        if(SocketUtil.ontaskMap.containsKey(id)){
            String sn = SocketUtil.ontaskMap.get(id).getEquipmentSn();
            CzEquipment ce = equipmentService.selectEquipmentInfo(sn);
            Socket socket = SocketUtil.gyroscopeSocketMap.get(ce.getGyroscopeCode()).getSocket();
            if(socket!=null && !socket.isClosed()){
                try {
                    SocketUtil.sendData("010600040000C80B", socket.getOutputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        //删除map中数据，停止采集线程
        if(SocketUtil.ontaskMap.containsKey(id)){
            SocketUtil.ontaskMap.remove(id);
        }
        CzCollectionTask cct = new CzCollectionTask();
        cct.setId(id);
        cct.setTaskStatus("2");
        czCollectionTaskService.updateCzCollectionTask(cct);
        CzTemperatureData q = new CzTemperatureData();
        q.setTaskId(id);
        //计算毫秒数
        List<CzTemperatureData>  temperatureDataList = czTemperatureDataService.selectCzTemperatureDataList(q);
        long ms = 0L;
        for (int i = 0; i < temperatureDataList.size(); i++) {

            CzTemperatureData tem = temperatureDataList.get(i);
            if(i==0){
                tem.setWarmingTime(0.0);
                ms = tem.getDataTime();
            }else {

                double db = (tem.getDataTime() - ms);
                System.err.println("ms1===========》"+tem.getDataTime());
                System.err.println("ms2===========》"+ms);
                System.err.println("ms差===========》"+ms);
                BigDecimal b1 = new BigDecimal(Double.toString(db));
                BigDecimal b2 = new BigDecimal("1000");
                double resultValue=b1.divide(b2, 3, BigDecimal.ROUND_HALF_UP).doubleValue();

                System.err.println(resultValue);
                tem.setWarmingTime(resultValue);
            }
            czTemperatureDataService.updateCzTemperatureData(tem);
        }
        AjaxResult result = AjaxResult.success();
        return result;
    }
    @GetMapping("/startHeat/{id}")
    public AjaxResult startHeat(@PathVariable("id")Long id) {
        //开始加热
        if(SocketUtil.ontaskMap.containsKey(id)){
            String sn = SocketUtil.ontaskMap.get(id).getEquipmentSn();
            CzEquipment ce = equipmentService.selectEquipmentInfo(sn);
            Socket socket = SocketUtil.gyroscopeSocketMap.get(ce.getGyroscopeCode()).getSocket();
            if(socket!=null && !socket.isClosed()){
                try {
                    SocketUtil.sendData("01060004000109CB", socket.getOutputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        AjaxResult result = AjaxResult.success();
        return result;
    }
    @GetMapping("/stopHeat/{id}")
    public AjaxResult stopHeat(@PathVariable("id")Long id) {
        //停止加热
        if(SocketUtil.ontaskMap.containsKey(id)){
            String sn = SocketUtil.ontaskMap.get(id).getEquipmentSn();
            CzEquipment ce = equipmentService.selectEquipmentInfo(sn);
            Socket socket = SocketUtil.gyroscopeSocketMap.get(ce.getGyroscopeCode()).getSocket();
            if(socket!=null && !socket.isClosed()){
                try {
                    SocketUtil.sendData("010600040000C80B", socket.getOutputStream());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        AjaxResult result = AjaxResult.success();
        return result;
    }
    @GetMapping("/findTempData/{id}")
    public AjaxResult findTempData(@PathVariable("id")String id)
    {

        //查询数据
        List<CzTemperatureData> ctdList = czTemperatureDataService.findTempData(id);
        //处理时间
        long ms = 0;
        for (int i = 0; i < ctdList.size(); i++) {
            CzTemperatureData tem = ctdList.get(i);
            if(i==0){
                tem.setWarmingTime(0.3);
                ms = tem.getDataTime();
            }else {
                double db = (tem.getDataTime() - ms);
                System.err.println("ms1===========》"+tem.getDataTime());
                System.err.println("ms2===========》"+ms);
                System.err.println("ms差===========》"+ms);
                BigDecimal b1 = new BigDecimal(Double.toString(db));
                BigDecimal b2 = new BigDecimal("1000");
                double resultValue=b1.divide(b2, 3, BigDecimal.ROUND_HALF_UP).doubleValue();
                tem.setWarmingTime(resultValue+0.3);
            }
        }
        return AjaxResult.success(ctdList);
    }

    /**
     * 修改任务数据
     */
    @PreAuthorize("@ss.hasPermi('baseinfo:collectionTask:edit')")
    @Log(title = "任务数据", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody CzCollectionTask czCollectionTask)
    {
        return toAjax(czCollectionTaskService.updateCzCollectionTask(czCollectionTask));
    }

    /**
     * 删除任务数据
     */
    @PreAuthorize("@ss.hasPermi('baseinfo:collectionTask:remove')")
    @Log(title = "任务数据", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(czCollectionTaskService.deleteCzCollectionTaskByIds(ids));
    }


    /**
     * 导出反演数据
     */
    @GetMapping("/exportData/{id}")
    public AjaxResult exportData(@PathVariable("id") Long id) throws Exception {
        //生成压缩文件
        CzCollectionTask task = czCollectionTaskService.selectCzCollectionTaskById(id);
        zipMultiFile(VibrationConfig.getInversionPath()+"/"+ task.getId()+"/", VibrationConfig.getInversionPath()+"/"+ "data"+task.getId()+".zip", true);
        String path=VibrationConfig.getInversionPath()+"/"+ "data"+task.getId()+".zip";
        File file = new File(path);
        if(file.exists()){
            String url = serverConfig.getUrl()+ Constants.RESOURCE_PREFIX + "/inversion/"+"data"+task.getId()+".zip";
            return AjaxResult.success("文件存在",url);
        }
        return AjaxResult.success("文件不存在");
    }

    /**
     * 导出温度数据
     * @param filepath
     * @param zippath
     * @param dirFlag
     */
    @GetMapping("/exportTempData/{id}")
    public AjaxResult exportTempData(@PathVariable("id") Long id) throws Exception {
        CzCollectionTask task = czCollectionTaskService.selectCzCollectionTaskById(id);
        zipMultiFile(VibrationConfig.getInversionPath()+"/"+ task.getId()+"/", VibrationConfig.getInversionPath()+"/"+ "data"+task.getId()+".zip", true);
        String path=VibrationConfig.getInversionPath()+"/"+ "data"+task.getId()+".zip";
        File file = new File(path);
        if(file.exists()){
            String url = serverConfig.getUrl()+ Constants.RESOURCE_PREFIX + "/inversion/"+"data"+task.getId()+".zip";
            return AjaxResult.success("文件存在",url);
        }
        return AjaxResult.success("文件不存在");
    }



    public static void zipMultiFile(String filepath ,String zippath, boolean dirFlag) {
        try {
            File file = new File(filepath);// 要被压缩的文件夹
            File zipFile = new File(zippath);
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
            if(file.isDirectory()){
                File[] files = file.listFiles();
                for(File fileSec:files){
                    if(dirFlag){
                        recursionZip(zipOut, fileSec, file.getName() + "/");
                    }else{
                        recursionZip(zipOut, fileSec, "");
                    }
                }
            }
            zipOut.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void recursionZip(ZipOutputStream zipOut, File file, String baseDir) throws Exception{
        if(file.isDirectory()){
            File[] files = file.listFiles();
            if(files.length > 0){
                for(File fileSec:files){
                    recursionZip(zipOut, fileSec, baseDir + file.getName() + "/");
                }
            }else{
                zipOut.putNextEntry(new ZipEntry(baseDir + file.getName() + "/"));
            }
        }else{
            byte[] buf = new byte[1024];
            InputStream input = new FileInputStream(file);
            zipOut.putNextEntry(new ZipEntry(baseDir + file.getName()));
            int len;
            while((len = input.read(buf)) != -1){
                zipOut.write(buf, 0, len);
            }
            input.close();
        }
    }


}
